package com.cn.JUC.utils.case11;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @Title CompletableFuture
 * @Description CompletableFuture工具类4个静态方法应用
 * 常用方法说明：1）runAsync无返回值，supplyAsync有返回值
 *             2）支持自定义线程池，烈建议你要根据不同的业务类型创建不同的线程池，以避免互相干扰。
 *
 * 烧水泡茶逻辑：       洗水壶-烧开水-（泡茶）1
 *              洗茶壶-洗茶杯-拿茶叶-（泡茶）2
 *              其中，1要等待2执行完毕再继续
 *
 * @Author CAI ZHAI
 * @Date 2021/9/6 16:04
 **/
public class BoilWaterToMakeTea2{
    public static void main(String[] args){
        boilWaterToMakeTea2();
    }
    
    public static void boilWaterToMakeTea2(){
        //任务1：洗水壶->烧开水
        CompletableFuture<Void> f1 = CompletableFuture.runAsync(()->{
            System.out.println("T1:洗水壶...");
            sleep(1);
        
            System.out.println("T1:烧开水...");
            sleep(5);
        });
        //任务2：洗茶壶->洗茶杯->拿茶叶
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(()->{
            System.out.println("T2:洗茶壶...");
            sleep(1);
        
            System.out.println("T2:洗茶杯...");
            sleep(2);
        
            System.out.println("T2:拿茶叶...");
            sleep(1);
            return "龙井";
        });
        //任务3：任务1和任务2完成后执行：泡茶
        CompletableFuture<String> f3 = f1.thenCombine(f2, (__, tf)->{
            System.out.println("T1:拿到茶叶:" + tf);
            System.out.println("T1:泡茶...");
            return "上茶:" + tf;
        });
    
        //等待任务3执行结果
        System.out.println(f3.join());
    }
    
    static void sleep(int t) {
        try {
            TimeUnit.SECONDS.sleep(t);
        }catch(InterruptedException e){}
    }
// 一次执行结果：
    /*T1:洗水壶...
    T2:洗茶壶...
    T1:烧开水...
    T2:洗茶杯...
    T2:拿茶叶...
    T1:拿到茶叶:龙井
    T1:泡茶...
    上茶:龙井*/
}
